package com.tpc.control.bean;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;

import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import javax.faces.event.ActionEvent;

import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.CellStyle;
import org.apache.poi.ss.usermodel.DataFormat;
import org.apache.poi.ss.usermodel.Font;
import org.apache.poi.ss.usermodel.Row;
import org.richfaces.component.UIColumn;
import org.richfaces.component.UIDataTable;
import org.richfaces.model.Ordering;

import com.tpc.control.jpa.CommonData;
import com.tpc.control.jpa.Con030Report;
import com.tpc.control.jpa.Con030ReportGreigeOver;
import com.tpc.control.jpa.Division;
import com.tpc.control.jpa.PlanGreige;
import com.tpc.control.jpa.SaleData;
import com.tpc.control.jpa.SaleDataDAO;
import com.tpc.control.jpa.Status;
import com.tpc.control.jpa.StatusDAO;
import com.tpc.control.util.Formatting;

public class Con030 {
	private String companyFrom;
	private String companyTo;
	private String divisionFrom;
	private String divisionTo;
	private String customerFrom;
	private String customerTo;
	private String customerPoFrom;
	private String customerPoTo;
	private String saleOrderFrom;
	private String saleOrderTo;
	private Date saleDueDateFrom;
	private Date saleDueDateTo;
	private String endUser;

	private List<Con030Report> reports;
	private List<Status> overDueStatusList;
	private Con030Report totalLine;

	private List<CommonData> selectDyeOver;
	private List<Con030ReportGreigeOver> selectGreigeOver;
	
	public List<CommonData> getSelectDyeOver() {
		return selectDyeOver;
	}

	public void setSelectDyeOver(List<CommonData> selectDyeOver) {
		this.selectDyeOver = selectDyeOver;
	}

	public List<Con030ReportGreigeOver> getSelectGreigeOver() {
		return selectGreigeOver;
	}

	public void setSelectGreigeOver(List<Con030ReportGreigeOver> selectGreigeOver) {
		this.selectGreigeOver = selectGreigeOver;
	}
	
	public List<Con030Report> getReports() {
		return reports;
	}

	public void setReports(List<Con030Report> reports) {
		this.reports = reports;
	}

	public List<Status> getOverDueStatusList() {
		return overDueStatusList;
	}

	public void setOverDueStatusList(List<Status> overDueStatusList) {
		this.overDueStatusList = overDueStatusList;
	}

	public Con030Report getTotalLine() {
		return totalLine;
	}

	public void setTotalLine(Con030Report totalLine) {
		this.totalLine = totalLine;
	}
	
	public String getEndUser() {
		return Formatting.checkStringNull(endUser);
	}

	public void setEndUser(String endUser) {
		this.endUser = endUser;
	}

	public String getCompanyFrom() {
		return Formatting.checkStringNull(companyFrom);
	}

	public void setCompanyFrom(String companyFrom) {
		this.companyFrom = companyFrom;
	}

	public String getCompanyTo() {
		return Formatting.checkStringNull(companyTo);
	}

	public void setCompanyTo(String companyTo) {
		this.companyTo = companyTo;
	}

	public String getDivisionFrom() {
		return Formatting.checkStringNull(divisionFrom);
	}

	public void setDivisionFrom(String divisionFrom) {
		this.divisionFrom = divisionFrom;
	}

	public String getDivisionTo() {
		return Formatting.checkStringNull(divisionTo);
	}

	public void setDivisionTo(String divisionTo) {
		this.divisionTo = divisionTo;
	}

	public String getCustomerFrom() {
		return Formatting.checkStringNull(customerFrom);
	}

	public void setCustomerFrom(String customerFrom) {
		this.customerFrom = customerFrom;
	}

	public String getCustomerTo() {
		return Formatting.checkStringNull(customerTo);
	}

	public void setCustomerTo(String customerTo) {
		this.customerTo = customerTo;
	}

	public String getCustomerPoFrom() {
		return Formatting.checkStringNull(customerPoFrom);
	}

	public void setCustomerPoFrom(String customerPoFrom) {
		this.customerPoFrom = customerPoFrom;
	}

	public String getCustomerPoTo() {
		return Formatting.checkStringNull(customerPoTo);
	}

	public void setCustomerPoTo(String customerPoTo) {
		this.customerPoTo = customerPoTo;
	}

	public String getSaleOrderFrom() {
		return Formatting.checkStringNull(saleOrderFrom);
	}

	public void setSaleOrderFrom(String saleOrderFrom) {
		this.saleOrderFrom = saleOrderFrom;
	}

	public String getSaleOrderTo() {
		return Formatting.checkStringNull(saleOrderTo);
	}

	public void setSaleOrderTo(String saleOrderTo) {
		this.saleOrderTo = saleOrderTo;
	}

	public Date getSaleDueDateFrom() {
		return saleDueDateFrom;
	}

	public void setSaleDueDateFrom(Date saleDueDateFrom) {
		this.saleDueDateFrom = saleDueDateFrom;
	}

	public Date getSaleDueDateTo() {
		return saleDueDateTo;
	}

	public void setSaleDueDateTo(Date saleDueDateTo) {
		this.saleDueDateTo = saleDueDateTo;
	}
	
	public String showReport() {
		reports = new ArrayList();
		totalLine = new Con030Report();
		SaleDataDAO saleDataDao = new SaleDataDAO();
		HashMap saleHash = new HashMap();
		List<Division> divisions = new ArrayList();
		List<SaleData> saleDatas = saleDataDao.findByReport(companyFrom,
				companyTo, divisionFrom, divisionTo, customerFrom, customerTo,
				saleOrderFrom, saleOrderTo, saleDueDateFrom, saleDueDateTo,
				customerPoFrom, customerPoTo, endUser);
		StatusDAO statusDao = new StatusDAO();
		//statusList = statusDao.findAll();
		overDueStatusList = statusDao.findByStatusType("CON030");
		for (int i = 0; i < saleDatas.size(); i++) {
			SaleData sale = saleDatas.get(i);
			List<SaleData> saleByDivison = new ArrayList();
			if (saleHash.containsKey(sale.getDivision())) {
				saleByDivison = (List<SaleData>) saleHash.get(sale
						.getDivision());
			} else {
				divisions.add(sale.getDivision());
			}
			saleByDivison.add(sale);
			saleHash.put(sale.getDivision(), saleByDivison);
		}
		
		for (int i = 0; i < divisions.size(); i++) {
			Con030Report item = new Con030Report();
			Division division = divisions.get(i);
			List<SaleData> saleByDivision = (List<SaleData>) saleHash
					.get(division);
			item.setDivision(division);
			item.setSaleDatas(saleByDivision);
			item.setTotalOrder(saleByDivision.size());
			totalLine.setTotalOrder(totalLine.getTotalOrder()
					+ saleByDivision.size());
			for (int j = 0; j < saleByDivision.size(); j++) {
				SaleData sale = saleByDivision.get(j);
				item.setTotalOrderAmount(item.getTotalOrderAmount()
						+ sale.getOrderAmount());
				totalLine.setTotalOrderAmount(totalLine.getTotalOrderAmount()
						+ sale.getOrderAmount());
				if (sale.getCompleteFlag().equalsIgnoreCase("X")) {
					item.setTotalComplete(item.getTotalComplete() + 1);
					item.setTotalCompleteAmount(item.getTotalCompleteAmount()
							+ sale.getCompleteAmount());

					totalLine
							.setTotalComplete(totalLine.getTotalComplete() + 1);
					totalLine.setTotalCompleteAmount(totalLine
							.getTotalCompleteAmount()
							+ sale.getCompleteAmount());
				} else {
					item.setTotalRemain(item.getTotalRemain() + 1);
					item.setTotalRemainAmount(item.getTotalRemainAmount()
							+ sale.getRemainAmount());

					totalLine.setTotalRemain(totalLine.getTotalRemain() + 1);
					totalLine.setTotalRemainAmount(totalLine
							.getTotalRemainAmount()
							+ sale.getRemainAmount());
					
					Iterator iter = sale.getPlanGreiges().iterator();
					while (iter.hasNext()) {
						PlanGreige aPlanGreige = (PlanGreige)iter.next();
						CommonData aCommon = aPlanGreige.getCommonData();
						int x=0;
						if (overDueStatusList.get(x).retrieveStatusMappingString()
								.contains(aCommon.getOverdueStatus())) {
							item.getTotalStatus().set(x,item.getTotalStatus().get(x) + 1);
							item.setAllTotalStatus(item.getAllTotalStatus() + 1);
							item.getTotalStatusDetail().get(x).add(aCommon);
							
							item.getTotalStatusSaleDetail().get(x).add(new Con030ReportGreigeOver(sale, aCommon, aPlanGreige));

							totalLine.getTotalStatus().set(x,totalLine.getTotalStatus().get(x) + 1);
							totalLine.setAllTotalStatus(totalLine.getAllTotalStatus() + 1);
							totalLine.getTotalStatusDetail().get(x).add(aCommon);
							break;
						}
					}
					
					List<CommonData> saleCommonData = sale.retrieveCommonDatasList();
					for (int k = 0; k < saleCommonData.size(); k++) {
						CommonData aCommon = saleCommonData.get(k);
						int x=1;
						if (overDueStatusList.get(x).retrieveStatusMappingString()
								.contains(aCommon.getOverdueStatus())) {
							item.getTotalStatus().set(x,item.getTotalStatus().get(x) + 1);
							item.setAllTotalStatus(item.getAllTotalStatus() + 1);
							item.getTotalStatusDetail().get(x).add(aCommon);

							totalLine.getTotalStatus().set(x,totalLine.getTotalStatus().get(x) + 1);
							totalLine.setAllTotalStatus(totalLine.getAllTotalStatus() + 1);
							totalLine.getTotalStatusDetail().get(x).add(aCommon);
							break;
						}
					}
				}
			}
			reports.add(item);
		}
		return "con031";
	}
	public void downloadSummaryToExcel(ActionEvent event) {
		javax.faces.context.FacesContext conText = javax.faces.context.FacesContext
				.getCurrentInstance();
		javax.servlet.http.HttpServletResponse response = (javax.servlet.http.HttpServletResponse) conText
				.getExternalContext().getResponse();
		try {
			HSSFWorkbook wb = new HSSFWorkbook();
			HSSFSheet sheet1 = wb.createSheet("Summary");
			sheet1.createFreezePane(1, 11);
			CellStyle styleAmount = wb.createCellStyle();
			DataFormat format = wb.createDataFormat();
			styleAmount.setDataFormat(format.getFormat("#,##0.00"));

			CellStyle styleHeader1 = wb.createCellStyle();
			Font font =wb.createFont();
            font.setBoldweight(Font.BOLDWEIGHT_BOLD);
            styleHeader1.setFont(font);
            
            generateHeaderRow(sheet1, 0, styleHeader1);
            generateSummaryRow(sheet1, 10, styleAmount);
            generateTotalRow(sheet1, reports.size()+ 12, styleAmount);
            
			response.setContentType("application/vnd.ms-excel");
			response.setHeader("Content-Disposition","attachment; filename=con030_summary.xls");
			javax.servlet.ServletOutputStream out = response.getOutputStream();
			
			wb.write(out);

			out.close();
		} catch (Exception e) {
			e.printStackTrace();
		}
		conText.getApplication().getStateManager().saveSerializedView(conText);
		conText.responseComplete();
	}
	
	private void generateHeaderRow(HSSFSheet sheet1, int noRow, CellStyle styleHeader1) {
		// TODO Auto-generated method stub
		Row aRow = sheet1.createRow(noRow);
		createCell(aRow, (short)0, "[CON-030] Production Control System Summary", styleHeader1);
		createCell(aRow, (short)7, "Run Date: ", styleHeader1);
		createCell(aRow, (short)8, Formatting.DateToFormat(Calendar.getInstance().getTime(), "dd/MM/yyyy HH:mm:ss"), styleHeader1);
		
		aRow = sheet1.createRow(++noRow);
		aRow.createCell((short)0).setCellValue("Company");
		aRow.createCell((short)1).setCellValue(companyFrom);
		aRow.createCell((short)2).setCellValue("to");
		aRow.createCell((short)3).setCellValue(companyTo);
		aRow = sheet1.createRow(++noRow);
		aRow.createCell((short)0).setCellValue("Division");
		aRow.createCell((short)1).setCellValue(divisionFrom);
		aRow.createCell((short)2).setCellValue("to");
		aRow.createCell((short)3).setCellValue(divisionTo);
		aRow = sheet1.createRow(++noRow);
		aRow.createCell((short)0).setCellValue("Customer No.");
		aRow.createCell((short)1).setCellValue(customerFrom);
		aRow.createCell((short)2).setCellValue("to");
		aRow.createCell((short)3).setCellValue(customerTo);
		aRow = sheet1.createRow(++noRow);
		aRow.createCell((short)0).setCellValue("Customer PO No.");
		aRow.createCell((short)1).setCellValue(customerPoFrom);
		aRow.createCell((short)2).setCellValue("to");
		aRow.createCell((short)3).setCellValue(customerPoTo);
		aRow = sheet1.createRow(++noRow);
		aRow.createCell((short)0).setCellValue("Sale Order");
		aRow.createCell((short)1).setCellValue(saleOrderFrom);
		aRow.createCell((short)2).setCellValue("to");
		aRow.createCell((short)3).setCellValue(saleOrderTo);
		aRow = sheet1.createRow(++noRow);
		aRow.createCell((short)0).setCellValue("Due Date");
		aRow.createCell((short)1).setCellValue(Formatting.DateToFormat(saleDueDateFrom, "dd/MM/yyyy"));
		aRow.createCell((short)2).setCellValue("to");
		aRow.createCell((short)3).setCellValue(Formatting.DateToFormat(saleDueDateTo, "dd/MM/yyyy"));
		aRow = sheet1.createRow(++noRow);
		aRow.createCell((short)0).setCellValue("End User Code");
		aRow.createCell((short)1).setCellValue(endUser);
		
		aRow = sheet1.createRow((short)noRow+3);
		createCell(aRow, (short)0, "Division", styleHeader1);
		createCell(aRow, (short)1, Formatting.getMessageBundle().getString("tot_order"), styleHeader1);
		createCell(aRow, (short)2, Formatting.getMessageBundle().getString("tot_order_amount"), styleHeader1);
		createCell(aRow, (short)3, Formatting.getMessageBundle().getString("tot_complete"), styleHeader1);
		createCell(aRow, (short)4, Formatting.getMessageBundle().getString("tot_complete_amount"), styleHeader1);
		createCell(aRow, (short)5, Formatting.getMessageBundle().getString("tot_remain"), styleHeader1);
		createCell(aRow, (short)6, Formatting.getMessageBundle().getString("tot_remain_amount"), styleHeader1);
		createCell(aRow, (short)7, Formatting.getMessageBundle().getString("tot_overdue"), styleHeader1);
		
		int col = 7;
		for (int i=0;i<Con030Report.COLUMNS;i++) {
			createCell(aRow, (short)++col, overDueStatusList.get(i).getStatusName(), styleHeader1);
		}
	}
	
	private void generateSummaryRow(HSSFSheet sheet1, int noRow, CellStyle styleAmount) {
		// TODO Auto-generated method stub
		for (int x=0;x<reports.size();x++) {
			Con030Report item = reports.get(x);
			Row aRow = sheet1.createRow((short)++noRow);
			aRow.createCell((short)0).setCellValue(item.getDivision().getDivision());
			aRow.createCell((short)1).setCellValue(item.getTotalOrder());
			createCell(aRow, (short)2, item.getTotalOrderAmount(), styleAmount);
			aRow.createCell((short)3).setCellValue(item.getTotalComplete());
			createCell(aRow, (short)4, item.getTotalCompleteAmount(), styleAmount);
			aRow.createCell((short)5).setCellValue(item.getTotalRemain());
			createCell(aRow, (short)6, item.getTotalRemainAmount(), styleAmount);
			aRow.createCell((short)7).setCellValue(item.getAllTotalStatus());
			int col = 7;
			for (int i=0;i<Con030Report.COLUMNS;i++) {
				if (item.getTotalStatus().get(i) == 0) {
					aRow.createCell((short)++col).setCellValue("");
				} else {
					aRow.createCell((short)++col).setCellValue(item.getTotalStatus().get(i));
				}
			}
			
		}
		
	}
	
	private void generateTotalRow(HSSFSheet sheet1, int noRow, CellStyle styleAmount) {
		// TODO Auto-generated method stub
		Row aRow = sheet1.createRow((short)noRow);
		aRow.createCell((short)0).setCellValue("Total");
		aRow.createCell((short)1).setCellValue(totalLine.getTotalOrder());
		createCell(aRow, (short)2, totalLine.getTotalOrderAmount(), styleAmount);
		aRow.createCell((short)3).setCellValue(totalLine.getTotalComplete());
		createCell(aRow, (short)4, totalLine.getTotalCompleteAmount(), styleAmount);
		aRow.createCell((short)5).setCellValue(totalLine.getTotalRemain());
		createCell(aRow, (short)6, totalLine.getTotalRemainAmount(), styleAmount);
		aRow.createCell((short)7).setCellValue(totalLine.getAllTotalStatus());
		int col = 7;
		for (int i=0;i<Con030Report.COLUMNS;i++) {
			aRow.createCell((short)++col).setCellValue(totalLine.getTotalStatus().get(i));
		}
		
	}
	
	private void createCell(Row row, short s, String value, CellStyle style) {
		// TODO Auto-generated method stub
		Cell aCell = row.createCell(s);
		aCell.setCellValue(value);
		aCell.setCellStyle(style);
	}
	
	private void createCell(Row row, short s, Double value, CellStyle style) {
		// TODO Auto-generated method stub
		Cell aCell = row.createCell(s);
		aCell.setCellValue(value);
		aCell.setCellStyle(style);
	}
	
	public void resetGreigeSorting() {
		UIDataTable table = (UIDataTable) FacesContext.getCurrentInstance()
				.getViewRoot().findComponent("con031Form:greigeTable");
		for (UIComponent column : table.getChildren()) {
			((UIColumn) column).setSortOrder(Ordering.UNSORTED);
		}
	}
	
	public void resetProductionSorting() {
		UIDataTable table = (UIDataTable) FacesContext.getCurrentInstance()
				.getViewRoot().findComponent("con031Form:productionTable");
		for (UIComponent column : table.getChildren()) {
			((UIColumn) column).setSortOrder(Ordering.UNSORTED);
		}
	}
}
